package com.gsafety.wellsfort.service.course;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gsafety.wellsfort.common.context.LoginContextUtil;
import com.gsafety.wellsfort.common.enums.RedisPrefixEnum;
import com.gsafety.wellsfort.common.enums.RoleGroupEnum;
import com.gsafety.wellsfort.common.util.*;
import com.gsafety.wellsfort.config.CacheManager;
import com.gsafety.wellsfort.dao.course.*;
import com.gsafety.wellsfort.dao.knowledge.*;
import com.gsafety.wellsfort.dao.organization.StudentDAO;
import com.gsafety.wellsfort.dao.organization.StudentLoginRelDAO;
import com.gsafety.wellsfort.dao.security.AdminDAO;
import com.gsafety.wellsfort.dao.security.RoleDAO;
import com.gsafety.wellsfort.dao.security.UserLoginDAO;
import com.gsafety.wellsfort.domain.dto.PageQueryDTO;
import com.gsafety.wellsfort.domain.dto.course.*;
import com.gsafety.wellsfort.domain.dto.courseware.CoursewareStudyDTO;
import com.gsafety.wellsfort.domain.dto.ids.CourseDto;
import com.gsafety.wellsfort.domain.dto.push.PushInfoDTO;
import com.gsafety.wellsfort.domain.model.course.*;
import com.gsafety.wellsfort.domain.model.knowledge.*;
import com.gsafety.wellsfort.domain.model.organization.Student;
import com.gsafety.wellsfort.domain.model.organization.StudentLoginRel;
import com.gsafety.wellsfort.domain.model.security.Admin;
import com.gsafety.wellsfort.domain.model.security.Role;
import com.gsafety.wellsfort.domain.model.security.UserLogin;
import com.gsafety.wellsfort.domain.vo.*;
import com.gsafety.wellsfort.service.common.IPushService;
import com.gsafety.wellsfort.service.security.IAdminService;
import com.gsafety.wellsfort.service.task.LessonPeriodPublishTask;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CourseService {
    @Autowired(required = false)
    CourseDAO courseDAO;

    @Autowired(required = false)
    LessonPeriodDAO lessonPeriodDAO;

    @Autowired(required = false)
    CourseRangeDAO courseRangeDAO;

    @Autowired(required = false)
    CoursewareDAO coursewareDAO;

    @Autowired(required = false)
    TeachingMaterialDAO materialDAO;

    @Autowired(required = false)
    TeachingAidDAO teachingAidDAO;

    @Autowired(required = false)
    WorkDAO workDAO;

    @Autowired(required = false)
    AdminDAO adminDAO;

    @Autowired(required = false)
    ExamPaperDAO examkDAO;

    @Autowired(required = false)
    StudentExamDAO studentExamDAO;

    @Autowired(required = false)
    StudentWorkDAO studentWorkDAO;

    @Autowired(required = false)
    WorkPublishDAO workPublishDAO;

    @Autowired(required = false)
    ExamPublishDAO examPublishDAO;

    @Autowired(required = false)
    WorkPublishRangeDAO workPublishRangeDAO;

    @Autowired(required = false)
    ExamPublishRangeDAO examPublishRangeDAO;

    @Autowired(required = false)
    LearningProgressDAO learningProgressDAO;

    @Autowired(required = false)
    StudentDAO studentDAO;

    @Autowired
    IAdminService adminService;

    @Autowired
    UserLoginDAO userLoginDAO;

    @Autowired(required = false)
    StudentLoginRelDAO studentLoginRelDAO;

    @Autowired
    private RoleDAO roleDAO;

    @Autowired
    IPushService pushService;

    @Autowired
    private CacheManager cacheManager;

    public Integer count() {
        return courseDAO.count();
    }

    /**
     * 发布历史课程给学生
     *
     * @param studentList
     * @param updated     是否更新历史数据(删除历史发布)
     * @param courseId    单个 courseId,否则发布所有
     */
    public void publishHistoryCourseToStudent(List<Student> studentList, boolean updated, Integer courseId) {
        List<CourseRange> courseRangeList = new ArrayList<>();
        if (courseId != null) {
            CourseRange courseRange = new CourseRange();
            courseRange.setCourseId(courseId);
            courseRangeList.add(courseRange);
        } else {
            courseRangeList = this.courseRangeDAO.selectCommonCourseRange();
        }
        if ((courseRangeList != null) && (courseRangeList.size() > 0)) {
            for (CourseRange courseRange : courseRangeList) {
                List<LessonPeriod> lessonPeriodList = this.lessonPeriodDAO.selectByCourseId(courseRange.getCourseId());
                if ((lessonPeriodList != null) && (lessonPeriodList.size() > 0)) {
                    for (LessonPeriod lessonPeriod : lessonPeriodList) {
                        if (lessonPeriod.getWorkId() != null) {
                            Map<String, Object> publishParamMap = new HashMap(8);
                            publishParamMap.put("courseId", lessonPeriod.getCourseId());
                            publishParamMap.put("lessonPeriodId", lessonPeriod.getId());
                            publishParamMap.put("workId", lessonPeriod.getWorkId());
                            WorkPublishVO workPublishVO = this.workPublishDAO.selectByParamMap(publishParamMap);
                            if (workPublishVO != null && workPublishVO.getId() != null) {
                                addOrUpdateStudentWork(workPublishVO.getId().intValue(), lessonPeriod, studentList, updated);
                            }
                        }
                        if (lessonPeriod.getExamId() != null) {
                            Map<String, Object> publishParamMap = new HashMap(8);
                            publishParamMap.put("courseId", lessonPeriod.getCourseId());
                            publishParamMap.put("lessonPeriodId", lessonPeriod.getId());
                            publishParamMap.put("examId", lessonPeriod.getExamId());
                            ExamPublishVO examPublishVO = this.examPublishDAO.selectByParamMap(publishParamMap);
                            if (examPublishVO != null && examPublishVO.getId() != null) {
                                addOrUpdateStudentExam(examPublishVO.getId().intValue(), lessonPeriod, studentList, updated);
                            }
                        }
                        addOrUpdateLearningProgress(lessonPeriod, studentList, updated);
                    }
                }
            }
        }
    }

    public ApiResponse<CourseDTO> saveBaseInfo(CourseDTO courseDto) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ApiResponse<CourseDTO> apiResponse = null;
        Course course = new Course();
        BeanUtils.copyProperties(courseDto, course);
        Integer courseId = courseDto.getId();
        course.setModified(LoginContextUtil.getAdmin().getId());
        course.setUpdateTime(new Date());
        course.setOnlineTime(courseDto.getOnlineTime() == null ? null : dateFormat.parse(courseDto.getOnlineTime()));
        if (courseId != null) {
            List<LessonPeriod> list = lessonPeriodDAO.selectByCourseId(courseId);
            if (courseDto.getIsOnline() == 1 && (list == null || list.size() == 0)) {
                return ApiResponse.error(ResultCode.PUBLISH_COURSE_NOT_CONTAINS_LESSON_PERIOD);
            }
            courseDAO.updateByPrimaryKeySelective(course);
        } else {
            if (courseDto.getIsOnline() == 1) {
                return ApiResponse.error(ResultCode.PUBLISH_COURSE_NOT_CONTAINS_LESSON_PERIOD);
            }
            course.setCreator(LoginContextUtil.getAdmin().getId());
            course.setCreateTime(new Date());
            courseDAO.insertSelective(course);
            courseDto.setId(course.getId());
        }

        apiResponse = ApiResponse.success(courseDto);
        return apiResponse;
    }

    public ApiResponse saveCourseRange(CourseRangeVO courseRangeVO) {
        CourseRange courseRange = null;
        List<CourseRangeDTO> dtoList = courseRangeVO.getList();
        boolean isPlatform = false;
        //清除原来的课程范围
        if (courseRangeVO.getCourseId() != null) {
            courseRangeDAO.deleteByCourseId(courseRangeVO.getCourseId());
            //清除线下自定义课程范围
            Course course = new Course();
            course.setId(courseRangeVO.getCourseId());
            course.setSchoolName(null);
            course.setClassName(null);
            course.setStudentNumber(0);
            course.setUpdateTime(new Date());
            courseDAO.updateByPrimaryKeySelective(course);
        }
        if (dtoList != null && dtoList.size() > 0) {
            CourseRangeDTO tmpDto = dtoList.get(0);
            Integer courseId = tmpDto.getCourseId();
            //平台级课程范围设置
            Course courseDB = courseDAO.selectByPrimaryKey(courseId);
            if (tmpDto.getSchoolId() == 1) {
                isPlatform = true;
                courseDB.setIsPlatform(1);
            } else {
                courseDB.setIsPlatform(0);
            }
            courseDAO.updateByPrimaryKeySelective(courseDB);
            //将DTO换DO
            List<CourseRange> rangList = new ArrayList<>();
            Admin admin = LoginContextUtil.getAdmin();
            for (CourseRangeDTO dto : dtoList) {
                courseRange = new CourseRange();
                BeanUtils.copyProperties(dto, courseRange);
                if (admin != null) courseRange.setModifyer(admin.getId());
                courseRange.setUpdateTime(new Date());
                if (admin != null) courseRange.setCreator(admin.getId());
                courseRange.setCreateTime(new Date());
                rangList.add(courseRange);
            }
            //批量调整课程范围
            courseRangeDAO.insertBatch(rangList);
        } else {
            //采取线下模式的自定义范围
            if (StringUtils.isNotEmpty(courseRangeVO.getSchoolName())) {
                Course course = new Course();
                course.setId(courseRangeVO.getCourseId());
                course.setSchoolName(courseRangeVO.getSchoolName());
                course.setClassName(courseRangeVO.getClassName());
                course.setStudentNumber(courseRangeVO.getStudentNumber());
                course.setUpdateTime(new Date());
                courseDAO.updateByPrimaryKeySelective(course);
            }
        }
        //课时发布,给app端推送push消息
        List<Student> studentList = new ArrayList<>();
        if (isPlatform) {
            //发布给所有学生
            studentList = studentDAO.selectAll();
        } else {
            List<CourseRange> rangeList = courseRangeDAO.selectByCourseId(courseRangeVO.getCourseId());
            for (CourseRange range : rangeList) {
                Integer classId = range.getClassId();
                studentList.addAll(studentDAO.selectByClassId(classId));
            }
        }
        List<LessonPeriod> lessonPeriodList = lessonPeriodDAO.selectByCourseId(courseRangeVO.getCourseId());
        if (lessonPeriodList != null && lessonPeriodList.size() > 0) {
            for (LessonPeriod lessonPeriod : lessonPeriodList) {
                if (lessonPeriod.getPublishState() == 1) {
                    pushMsgToApp(lessonPeriod, studentList);
                }
            }
        }
        /**
         *  发布历史课程给学生
         */
        this.publishHistoryCourseToStudent(studentList, true, courseRangeVO.getCourseId());
        return ApiResponse.success();
    }

    public ApiResponse<LessonPeriodDTO> addOrUpdateLessonPeriod(LessonPeriodDTO lessonPeriodDTO) throws Exception {
        ApiResponse apiResponse = null;
        LessonPeriod lessonPeriod = convertDto2Do(lessonPeriodDTO);
        boolean updated = lessonPeriod.getId() != null;
        if (updated) {
            lessonPeriodDAO.updateByPrimaryKeySelective(lessonPeriod);
        } else {
            lessonPeriodDAO.insertSelective(lessonPeriod);
        }

        Integer courseId = lessonPeriodDTO.getCourseId();
        Course course = courseDAO.selectByPrimaryKey(courseId);
        //添加作业发布记录
        int workPublishId = addOrUpdateWorkPublish(lessonPeriod);
        //添加试卷发布记录
        int examPublishId = addOrUpdateExamPublish(lessonPeriod);
        if (lessonPeriodDTO.getIsWorkPublish() == 1) {
            workPublishRangeDAO.deleteByWorkPublishId(workPublishId);
            List<Student> studentList = new ArrayList<>();
            if (course.getIsPlatform() == 1) {
                //发布给所有学生
                studentList = studentDAO.selectAll();
            } else {
                List<CourseRange> courseRangeList = courseRangeDAO.selectByCourseId(courseId);
                WorkPublishRange wkPubRange;
                for (CourseRange courseRange : courseRangeList) {
                    Integer classId = courseRange.getClassId();
                    studentList.addAll(studentDAO.selectByClassId(classId));
                    //创建课时作业发布范围
                    wkPubRange = WorkPublishRange.builder().classId(courseRange.getClassId())
                            .schoolId(courseRange.getSchoolId())
                            .creator(LoginContextUtil.getAdmin().getId())
                            .createTime(new Date())
                            .workPublishId(workPublishId).build();
                    workPublishRangeDAO.insert(wkPubRange);
                }
            }
            //添加学生作业记录
            addOrUpdateStudentWork(workPublishId, lessonPeriod, studentList, true);
        }
        if (lessonPeriodDTO.getIsExamPublish() == 1) {
            List<Student> studentList = new ArrayList<>();
            if (course.getIsPlatform() == 1) {
                //发布给所有学生
                studentList = studentDAO.selectAll();
            } else {
                List<CourseRange> courseRangeList = courseRangeDAO.selectByCourseId(courseId);
                examPublishRangeDAO.deleteByExamPublishId(examPublishId);
                ExamPublishRange exPubRange;
                for (CourseRange courseRange : courseRangeList) {
                    Integer classId = courseRange.getClassId();
                    studentList.addAll(studentDAO.selectByClassId(classId));

                    //创建考试发布范围
                    exPubRange = ExamPublishRange.builder().classId(courseRange.getClassId())
                            .schoolId(courseRange.getSchoolId())
                            .creator(LoginContextUtil.getAdmin().getId())
                            .createTime(new Date())
                            .examPublishId(examPublishId).build();
                    examPublishRangeDAO.insert(exPubRange);

                }
            }
            //添加学生考试
            addOrUpdateStudentExam(examPublishId, lessonPeriod, studentList, true);
        }
        List<Student> studentList = new ArrayList<>();
        if (course.getIsPlatform() == 1) {
            //发布给所有学生
            studentList = studentDAO.selectAll();
        } else {
            List<CourseRange> courseRangeList = courseRangeDAO.selectByCourseId(courseId);
            for (CourseRange courseRange : courseRangeList) {
                Integer classId = courseRange.getClassId();
                studentList.addAll(studentDAO.selectByClassId(classId));
            }
        }
        //添加课件学习进度
        addOrUpdateLearningProgress(lessonPeriod, studentList, true);
        //计算课程学习推荐总时长(=课程下面所有课时累计时长)
        Integer duration = 0;
        List<LessonPeriod> lessonPeriodList = lessonPeriodDAO.selectByCourseId(lessonPeriodDTO.getCourseId());
        if (lessonPeriodList != null && lessonPeriodList.size() > 0) {
            for (LessonPeriod period : lessonPeriodList) {
                duration = duration + period.getDuration();
            }
        }
        //更新课程推荐总时长
        Course newCourse = new Course();
        newCourse.setId(courseId);
        newCourse.setUpdateTime(new Date());
        newCourse.setDuration(duration);
        courseDAO.updateByPrimaryKeySelective(newCourse);
        //课时发布,给app端推送push消息
        pushMsgToApp(lessonPeriod, studentList);
        apiResponse = ApiResponse.success();
        return apiResponse;
    }

    /**
     * 给APP推送push消息
     *
     * @param lessonPeriod
     * @param studentList
     */
    private void pushMsgToApp(LessonPeriod lessonPeriod, List<Student> studentList) {
        if (lessonPeriod.getPublishState() != null && lessonPeriod.getPublishState() == 1 && studentList != null && studentList.size() > 0) {
            List<UserLogin> userLoginList = buildUserLoginList(studentList);
            //获取课时上课时间, 只在课程发布以后 在上课时间往前推一天 也就是24小时定时发布; 如果说已经小于24小时就立马推送
            if (lessonPeriod.getAttendClassTime().compareTo(DateUtil.nextDate()) < 0) {
                Map<String, Object> map = DateUtil.compareTimeDifference(lessonPeriod.getAttendClassTime(), new Date());
                PushInfoDTO pushInfoDTO = PushInfoDTO.builder().title(lessonPeriod.getName() + "课时即将上线").
                        message("还有" + map.get("hour") + "小时" + map.get("min") + "分钟," + lessonPeriod.getName() + "课时上线").deviceType("ALL").userLoginList(userLoginList).build();
                pushService.push(pushInfoDTO);
            } else {
                //大于24小时发布,放到延迟队列执行(push执行时间,老师授课时间前24小时推送)
                LessonPeriodPublishTask lessonPeriodPublishTask = new LessonPeriodPublishTask(DateUtil.getPrevDate(lessonPeriod.getAttendClassTime()).getTime(), pushService, userLoginList, lessonPeriod);
                DelayQueueProvider.put(lessonPeriodPublishTask);
            }
        }
    }


    /**
     * 通过学生查找对应登录id(学生和登录id一对多)
     *
     * @param studentList
     * @return
     */
    private List<UserLogin> buildUserLoginList(List<Student> studentList) {
        List<UserLogin> list = new ArrayList<>();
        if (studentList != null) {
            log.info("发布学生范围={}", JSON.toJSONString(studentList));
            for (Student student : studentList) {
                if (student != null) {
                    List<StudentLoginRel> studentLoginRelList = studentLoginRelDAO.selectByStudentId(student.getId());
                    if (studentLoginRelList != null && studentLoginRelList.size() > 0) {
                        for (StudentLoginRel studentLoginRel : studentLoginRelList) {
                            if (studentLoginRel != null) {
                                UserLogin userLogin = userLoginDAO.selectByPrimaryKey(studentLoginRel.getLoginId());
                                if (userLogin != null) {
                                    list.add(userLogin);
                                }
                            }
                        }
                    }
                }
            }
        }
        return list;
    }

    /**
     * 添加课件学习进度l
     *
     * @param lessonPeriod
     * @param studentList
     */
    private void addOrUpdateLearningProgress(LessonPeriod lessonPeriod, List<Student> studentList, boolean updated) {
        Date date = new Date();
        if (updated) {
            deleteLearningProgress(lessonPeriod);
        }
        if (StringUtils.isNotEmpty(lessonPeriod.getCoursewareIds())) {
            for (Student student : studentList) {
                String[] courseWareList = lessonPeriod.getCoursewareIds().split(",");
                for (String courseWareId : courseWareList) {
                    if (StringUtils.isNotEmpty(courseWareId)) {
                        LearningProgress learningProgress = new LearningProgress();
                        learningProgress.setLessonPeriodId(lessonPeriod.getId());
                        learningProgress.setCourseId(lessonPeriod.getCourseId());
                        learningProgress.setCoursewareId(Integer.parseInt(courseWareId));
                        learningProgress.setStudentId(student.getId());
                        learningProgress.setAccumulatedTime(0);
                        learningProgress.setCompleteState((byte) 0);
                        learningProgress.setVideoWatchTime(0);
                        learningProgress.setCreateTime(date);
                        Student stu = LoginContextUtil.getStudent();
                        if (stu != null) learningProgress.setCreator(stu.getId());
                        if (stu != null) learningProgress.setModifyer(stu.getId());
                        learningProgressDAO.insertSelective(learningProgress);
                    }
                }
            }
        }
    }

    /**
     * 更新学生课时试卷
     *
     * @param examPublishId
     * @param lessonPeriod
     * @param studentList
     */
    private void addOrUpdateStudentExam(int examPublishId, LessonPeriod lessonPeriod, List<Student> studentList, boolean updated) {
        if (updated) {
            deleteStudentExam(lessonPeriod);
        }
        if (lessonPeriod.getExamId() != null) {
            for (Student student : studentList) {
                StudentExam studentExam = new StudentExam();
                studentExam.setStudentId(student.getId());
                studentExam.setClassId(student.getClassId());
                studentExam.setExamPublishId(examPublishId);
                studentExam.setExamId(lessonPeriod.getExamId());
                studentExam.setCourseId(lessonPeriod.getCourseId());
                studentExam.setLessonPeriodId(lessonPeriod.getId());
                studentExam.setFinishState((byte) 0);
                studentExam.setPublishTime(new Date());
                studentExam.setLessonPeriodId(lessonPeriod.getId());
                studentExamDAO.insertSelective(studentExam);
            }
        }
    }

    /**
     * 更新学生课程作业
     *
     * @param workPublishId
     * @param lessonPeriod
     * @param studentList
     */
    private void addOrUpdateStudentWork(int workPublishId, LessonPeriod lessonPeriod, List<Student> studentList, boolean updated) {
        if (updated) {
            deleteStudentWork(lessonPeriod);
        }
        if (lessonPeriod.getWorkId() != null) {
            for (Student student : studentList) {
                StudentWork studentWork = new StudentWork();
                studentWork.setStudentId(student.getId());
                studentWork.setClassId(student.getClassId());
                studentWork.setWorkPublishId(workPublishId);
                studentWork.setWorkId(lessonPeriod.getWorkId());
                studentWork.setCourseId(lessonPeriod.getCourseId());
                studentWork.setFinishState((byte) 0);
                studentWork.setPublishTime(new Date());
                studentWork.setLessonPeriodId(lessonPeriod.getId());
                studentWorkDAO.insertSelective(studentWork);
            }
        }
    }

    /**
     * 添加作业发布记录
     *
     * @param lessonPeriod
     * @return
     */
    private int addOrUpdateWorkPublish(LessonPeriod lessonPeriod) {
        deleteWorkPublishByParam(lessonPeriod);
        WorkPublish workPublish = new WorkPublish();
        workPublish.setWorkId(lessonPeriod.getWorkId());
        workPublish.setPublishState(lessonPeriod.getIsWorkPublish() == null ? 0 : lessonPeriod.getIsWorkPublish().byteValue());
        workPublish.setCourseId(lessonPeriod.getCourseId());
        workPublish.setLessonPeriodId(lessonPeriod.getId());
        Admin admin = LoginContextUtil.getAdmin();
        workPublish.setPublishUserId(admin.getId());
        workPublish.setPublishTime(new Date());
        workPublish.setPublishNums(1);
        workPublish.setFinishNums(0);
        workPublishDAO.insertSelective(workPublish);
        return workPublish.getId();
    }

    /***
     * 添加试卷发布记录
     * @param lessonPeriod
     * @return
     */
    private int addOrUpdateExamPublish(LessonPeriod lessonPeriod) {
        deleteExamPublishByParam(lessonPeriod);
        ExamPublish examPublish = new ExamPublish();
        examPublish.setExamId(lessonPeriod.getExamId());
        examPublish.setPublishState(lessonPeriod.getIsExamPublish() == null ? 0 : lessonPeriod.getIsExamPublish().byteValue());
        examPublish.setCourseId(lessonPeriod.getCourseId());
        examPublish.setLessonPeriodId(lessonPeriod.getId());
        Admin admin = LoginContextUtil.getAdmin();
        examPublish.setPublishUserId(admin.getId());
        examPublish.setPublishTime(new Date());
        examPublish.setPublishNums(1);
        examPublish.setFinishNums(0);
        examPublishDAO.insertSelective(examPublish);
        return examPublish.getId();
    }

    /**
     * @param lessonPeriodDTO
     * @return
     */
    private LessonPeriod convertDto2Do(LessonPeriodDTO lessonPeriodDTO) throws Exception {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        LessonPeriod lessonPeriod = new LessonPeriod();
        BeanUtils.copyProperties(lessonPeriodDTO, lessonPeriod);
        lessonPeriod.setTeachingTime(lessonPeriodDTO.getTeachingTime() == null ? null : dateFormat.parse(lessonPeriodDTO.getTeachingTime()));
        lessonPeriod.setAttendClassTime(lessonPeriodDTO.getAttendClassTime() == null ? null : dateFormat.parse(lessonPeriodDTO.getAttendClassTime()));
        lessonPeriod.setIsAttendClass(lessonPeriodDTO.getIsAttendClass() == null ? null : lessonPeriodDTO.getIsAttendClass().byteValue());
        lessonPeriod.setIsTeaching(lessonPeriodDTO.getIsTeaching() == null ? null : lessonPeriodDTO.getIsTeaching().byteValue());
        lessonPeriod.setIsWorkPublish(lessonPeriodDTO.getIsWorkPublish() == null ? 0 : lessonPeriodDTO.getIsWorkPublish().byteValue());
        lessonPeriod.setIsExamPublish(lessonPeriodDTO.getIsExamPublish() == null ? 0 : lessonPeriodDTO.getIsExamPublish().byteValue());
        lessonPeriod.setPublishState(lessonPeriodDTO.getPublishState() == null ? 0 : lessonPeriodDTO.getPublishState());
        //课件、教具数据处理
        if (lessonPeriodDTO.getCoursewareIds() != null && lessonPeriodDTO.getCoursewareIds().size() > 0) {
            lessonPeriod.setCoursewareIds(lessonPeriodDTO.getCoursewareIds().stream().collect(Collectors.joining(",")));
        }
        if (lessonPeriodDTO.getTeachingAidIds() != null && lessonPeriodDTO.getTeachingAidIds().size() > 0) {
            lessonPeriod.setTeachingAidIds(lessonPeriodDTO.getTeachingAidIds().stream().collect(Collectors.joining(",")));
        }
        return lessonPeriod;
    }

    public ApiResponse deleteByCourseId(Integer id) {
        ApiResponse apiResponse = null;
        try {
            //先删除所有课时
            List<LessonPeriod> lessonPeriodList = lessonPeriodDAO.selectByCourseId(id);
            if (lessonPeriodList != null && lessonPeriodList.size() > 0) {
                for (LessonPeriod lessonPeriod : lessonPeriodList) {
                    deleteLessonPeriod(lessonPeriod.getId());
                }
            }
            //删除课程发布范围
            courseRangeDAO.deleteByCourseId(id);
            //删除redis中缓存热门课程信息
            cacheManager.delHashKey(RedisPrefixEnum.COURSE_VISIT_COUNT_PREFIX.getPrefix(), String.valueOf(id));
            //删除课程
            courseDAO.deleteByPrimaryKey(id);
            apiResponse = ApiResponse.success("课程删除成功");
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse deleteLessonPeriod(Integer lessonPeriodId) {
        ApiResponse apiResponse = null;
        try {
            LessonPeriod lessonPeriod = lessonPeriodDAO.selectByPrimaryKey(lessonPeriodId);
            deleteWorkPublishByParam(lessonPeriod);
            deleteExamPublishByParam(lessonPeriod);
            deleteStudentWork(lessonPeriod);
            deleteStudentExam(lessonPeriod);
            deleteLearningProgress(lessonPeriod);
            lessonPeriodDAO.deleteByPrimaryKey(lessonPeriodId);
            apiResponse = ApiResponse.success("课时删除成功");
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }

    /**
     * 删除课时相关的作业发布记录
     *
     * @param lessonPeriod
     */
    private void deleteWorkPublishByParam(LessonPeriod lessonPeriod) {
        //查找课时作业，试卷的发布记录
        Map<String, Object> publishParamMap = new HashMap<String, Object>(8);
        publishParamMap.put("courseId", lessonPeriod.getCourseId());
        publishParamMap.put("lessonPeriodId", lessonPeriod.getId());
        //先删除记录
        workPublishDAO.deleteByParamMap(publishParamMap);
    }

    /**
     * 删除课时相关的考试发布记录
     *
     * @param lessonPeriod
     */
    private void deleteExamPublishByParam(LessonPeriod lessonPeriod) {
        //查找课时作业，试卷的发布记录
        Map<String, Object> examParamMap = new HashMap<String, Object>(8);
        examParamMap.put("courseId", lessonPeriod.getCourseId());
        examParamMap.put("lessonPeriodId", lessonPeriod.getId());
        //先删除记录
        examPublishDAO.deleteByParamMap(examParamMap);
    }

    /**
     * 删除学生作业
     *
     * @param lessonPeriod
     */
    private void deleteStudentWork(LessonPeriod lessonPeriod) {
        Map<String, Object> param = new HashMap<>(8);
        param.put("courseId", lessonPeriod.getCourseId());
        param.put("lessonPeriodId", lessonPeriod.getId());
        //先删除记录(课程课时)
        studentWorkDAO.deleteByParamMap(param);
    }

    /**
     * 删除学生考试
     *
     * @param lessonPeriod
     */
    private void deleteStudentExam(LessonPeriod lessonPeriod) {
        Map<String, Object> param = new HashMap<>(8);
        param.put("courseId", lessonPeriod.getCourseId());
        param.put("lessonPeriodId", lessonPeriod.getId());
        //先删除记录(课程课时)
        studentExamDAO.deleteByParamMap(param);
    }

    /**
     * 删除学习进度
     *
     * @param lessonPeriod
     */
    public void deleteLearningProgress(LessonPeriod lessonPeriod) {
        Map<String, Object> param = new HashMap<>(8);
        param.put("courseId", lessonPeriod.getCourseId());
        param.put("lessonPeriodId", lessonPeriod.getId());
        //先删除记录(课程课时)
        learningProgressDAO.deleteByParamMap(param);
    }

    public ApiResponse<LessonPeriodVO> getLessonPeriod(LessonPeriodDetailDTO lessonPeriodDetailDTO) {
        ApiResponse<LessonPeriodVO> apiResponse = null;
        try {
            Integer studentId = null;
            if (LoginContextUtil.getStudent() != null) {
                studentId = LoginContextUtil.getStudent().getId();
            } else {
                return ApiResponse.error(ResultCode.ERROR, "学生未登录");
            }
            Integer lessonPeriodId = lessonPeriodDetailDTO.getLessonPeriodId();
            Integer courseId = lessonPeriodDetailDTO.getCourseId();
            LessonPeriod lessonPeriod = lessonPeriodDAO.selectByPrimaryKey(lessonPeriodId);
            LessonPeriodVO lessonPeriodVO = new LessonPeriodVO.VOBuilder(lessonPeriod).build();

            Map<String, Object> publishParamMap = new HashMap<String, Object>();
            publishParamMap.put("courseId", courseId);
            publishParamMap.put("lessonPeriodId", lessonPeriod.getId());
            if (lessonPeriod.getWorkId() != null) {
                publishParamMap.put("workId", lessonPeriod.getWorkId());
                WorkPublishVO workPublishVO = workPublishDAO.selectByParamMap(publishParamMap);
                if (workPublishVO != null) {
                    lessonPeriodVO.setWorkPublishId(workPublishVO.getId());
                }
            }
            if (lessonPeriod.getExamId() != null) {
                publishParamMap.put("examId", lessonPeriod.getExamId());
                ExamPublishVO examPublishVO = examPublishDAO.selectByParamMap(publishParamMap);
                if (examPublishVO != null) {
                    lessonPeriodVO.setExamPublishId(examPublishVO.getId());
                }
            }
            if (StringUtil.isNotEmpty(lessonPeriod.getCoursewareIds())) {
                String[] ids = lessonPeriod.getCoursewareIds().split(",");
                List<Courseware> coursewareList = new ArrayList<Courseware>();
                for (String id : ids) {
                    Map<String, Object> learningProgressParam = new HashMap<>(8);
                    Courseware courseware = coursewareDAO.selectByPrimaryKey(Integer.parseInt(id));
                    learningProgressParam.put("lessonPeriodId", lessonPeriodId);
                    learningProgressParam.put("courseId", courseId);
                    learningProgressParam.put("coursewareId", courseware.getId());
                    learningProgressParam.put("studentId", studentId);
                    List<LearningProgress> learningProgressList = learningProgressDAO.selectByMapParam(learningProgressParam);
                    if (learningProgressList != null && learningProgressList.size() > 0) {
                        courseware.setVideoWatchTime(learningProgressList.get(0).getVideoWatchTime());
                    }
                    coursewareList.add(courseware);
                }
                lessonPeriodVO.setCoursewareList(coursewareList);
            }
            Map<String, Object> learningProgressParam = publishParamMap;
            List<Courseware> list = lessonPeriodVO.getCoursewareList();
            Integer courseWareStudyTime = 0;
            for (Courseware courseware : list) {
                learningProgressParam.put("lessonPeriodId", lessonPeriodId);
                learningProgressParam.put("courseId", courseId);
                learningProgressParam.put("coursewareId", courseware.getId());
                learningProgressParam.put("studentId", studentId);
                List<LearningProgress> learningProgressList = learningProgressDAO.selectByMapParam(learningProgressParam);
                if (learningProgressList != null && learningProgressList.size() > 0) {
                    Double d = learningProgressList.get(0).getAccumulatedTime() * 1.00 / (courseware.getLearningTime() * 60);
                    courseware.setRate(getFormatRate(d));
                    courseWareStudyTime = courseWareStudyTime + learningProgressList.get(0).getAccumulatedTime();
                }
            }
            //课时的学习进度等于 课件的学习总时长/课时的建议时长
            //lessonPeriodVO.setRate(getFormatRate(courseWareStudyTime * 1.00 / lessonPeriodVO.getDuration()));
            lessonPeriodVO.setRate(getLessonPeriodRate(lessonPeriod));
            if (lessonPeriod.getTeachingMaterialId() != null) {
                TeachingMaterial tmaterial = materialDAO.selectByPrimaryKey(lessonPeriod.getTeachingMaterialId());
                lessonPeriodVO.setTeachingMaterial(tmaterial);
            }
            if (lessonPeriod.getTeacherId() != null) {
                Admin teacher = adminDAO.selectByPrimaryKey(lessonPeriod.getTeacherId());
                if (teacher != null) lessonPeriodVO.setTeacher(teacher);
            }
            if (lessonPeriod.getWorkId() != null) {
                Work w = workDAO.selectByPrimaryKey(lessonPeriod.getWorkId());
                //查询作业的完成状态
                MyWorkDTO myWorkDTO = new MyWorkDTO();
                myWorkDTO.setStudentId(studentId);
                myWorkDTO.setWorkId(lessonPeriod.getWorkId());
                myWorkDTO.setWorkPublishId(lessonPeriodVO.getWorkPublishId());
                List<StudentWork> workList = studentWorkDAO.selectByCondition(myWorkDTO);
                if (workList != null && workList.size() > 0) {
                    w.setFinishState(workList.get(0).getFinishState() == null ? 0 : workList.get(0).getFinishState().intValue());
                }
                w.setWorkPublishId(lessonPeriodVO.getWorkPublishId());
                lessonPeriodVO.setWork(w);
            }
            if (lessonPeriod.getExamId() != null) {
                ExamPaper paper = examkDAO.selectByPrimaryKey(lessonPeriod.getExamId());
                //查询试卷的完成状态
                MyExamDTO myExamDTO = new MyExamDTO();
                myExamDTO.setStudentId(studentId);
                myExamDTO.setExamId(lessonPeriod.getExamId());
                myExamDTO.setExamPublishId(lessonPeriodVO.getExamPublishId());
                List<StudentExam> examList = studentExamDAO.selectByCondition(myExamDTO);
                if (examList != null && examList.size() > 0) {
                    paper.setFinishState(examList.get(0).getFinishState() == null ? 0 : examList.get(0).getFinishState().intValue());
                }
                paper.setExamPublishId(lessonPeriodVO.getExamPublishId());
                lessonPeriodVO.setExamPaper(paper);
            }
            if (StringUtil.isNotEmpty(lessonPeriod.getTeachingAidIds())) {
                String[] ids = lessonPeriod.getTeachingAidIds().split(",");
                List<TeachingAid> tAidList = new ArrayList<TeachingAid>();
                for (String id : ids) {
                    TeachingAid taid = teachingAidDAO.selectByPrimaryKey(Integer.parseInt(id));
                    tAidList.add(taid);
                }
                lessonPeriodVO.setTeachingAidList(tAidList);
            }
            apiResponse = ApiResponse.success(lessonPeriodVO);
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            log.error("APP查询课时详情异常,exception={}", e);
        }
        return apiResponse;
    }

    private String getFormatRate(Double d) {
        if (d == null) {
            return "0";
        } else if (d >= 1) {
            return "1";
        } else {
            return String.valueOf(d);
        }
    }

    /**
     * 课时界面，一共有3个课件，一个作业、一个试卷，那么每一个内容所占总进度的百分之20 (课件只有学习完成才会统计进课时总进度)
     * 课程内容：
     * 课件1   占总进度百分之20
     * 课件2   占总进度百分之20
     * 课件3   占总进度百分之20 （建议学习时间3分钟，观看了1分钟，课件进度= 1分钟除以3/分钟，但是如果没有完整观看3分钟，那么占总进度的百分之0，观看3分钟，占总进度百分之20）
     * <p>
     * 作业   占总进度百分之20（作业完成就是百分之20，没有完成就是0）
     * 试卷   占总进度百分之20（试卷完成就是百分之20，没有完成就是0）
     *
     * @return
     */
    private String getLessonPeriodRate(LessonPeriod lessonPeriod) {
        if (lessonPeriod == null) {
            return "0";
        }
        Integer studentId = null;
        int total = 0, hasFinishCount = 0;
        if (LoginContextUtil.getStudent() != null) {
            studentId = LoginContextUtil.getStudent().getId();
        }
        Map<String, Object> learningProgressParam = new HashMap<>(8);
        if (StringUtils.isNotEmpty(lessonPeriod.getCoursewareIds())) {
            String[] ids = lessonPeriod.getCoursewareIds().split(",");
            total = total + ids.length;
            for (String id : ids) {
                Courseware courseware = coursewareDAO.selectByPrimaryKey(Integer.parseInt(id));
                learningProgressParam.put("lessonPeriodId", lessonPeriod.getId());
                learningProgressParam.put("courseId", lessonPeriod.getCourseId());
                learningProgressParam.put("coursewareId", courseware.getId());
                learningProgressParam.put("studentId", studentId);
                List<LearningProgress> learningProgressList = learningProgressDAO.selectByMapParam(learningProgressParam);
                if (learningProgressList != null && learningProgressList.size() > 0) {
                    //只有学习完成的课件才会被统计进课时总进度
                    if (learningProgressList.get(0).getCompleteState() == 1) {
                        hasFinishCount++;
                    }
                }
            }
        }
        if (lessonPeriod.getWorkId() != null) {
            total++;
            Map<String, Object> params = new HashMap<>(8);
            params.put("workId", lessonPeriod.getWorkId());
            params.put("courseId", lessonPeriod.getCourseId());
            params.put("lessonPeriodId", lessonPeriod.getId());
            WorkPublishVO workPublishVO = workPublishDAO.selectByParamMap(params);
            if (workPublishVO != null) {
                MyWorkDTO myWorkDTO = new MyWorkDTO();
                myWorkDTO.setStudentId(studentId);
                myWorkDTO.setWorkId(lessonPeriod.getWorkId());
                myWorkDTO.setWorkPublishId(workPublishVO.getId());
                List<StudentWork> studentWorkList = studentWorkDAO.selectByCondition(myWorkDTO);
                if (studentWorkList != null && studentWorkList.size() > 0) {
                    StudentWork studentWork = studentWorkList.get(0);
                    if (studentWork != null && studentWork.getFinishState() != null && studentWork.getFinishState() == 1) {
                        hasFinishCount++;
                    }
                }
            }
        }
        if (lessonPeriod.getExamId() != null) {
            total++;
            Map<String, Object> params = new HashMap<>(8);
            params.put("examId", lessonPeriod.getExamId());
            params.put("courseId", lessonPeriod.getCourseId());
            params.put("lessonPeriodId", lessonPeriod.getId());
            ExamPublishVO examPublishVO = examPublishDAO.selectByParamMap(params);
            if (examPublishVO != null) {
                MyExamDTO myExamDTO = new MyExamDTO();
                myExamDTO.setStudentId(studentId);
                myExamDTO.setExamId(lessonPeriod.getExamId());
                myExamDTO.setExamPublishId(examPublishVO.getId());
                List<StudentExam> studentExamList = studentExamDAO.selectByCondition(myExamDTO);
                if (studentExamList != null && studentExamList.size() > 0) {
                    StudentExam studentExam = studentExamList.get(0);
                    if (studentExam != null && studentExam.getFinishState() != null && studentExam.getFinishState() == 1) {
                        hasFinishCount++;
                    }
                }
            }
        }
        return getFormatRate(hasFinishCount * 1.0000 / total);
    }


    public ApiResponse<WorkPublishDTO> publishLessonPeriodWork(WorkPublishDTO workPublishDTO) {
        ApiResponse apiResponse = null;
        WorkPublish wkPublish = new WorkPublish();
        BeanUtils.copyProperties(workPublishDTO, wkPublish);
        try {
            //状态设置为已发布
            wkPublish.setPublishState(Byte.parseByte("1"));
            wkPublish.setPublishUserId(LoginContextUtil.getAdmin().getId());
            wkPublish.setPublishTime(new Date());
            workPublishDAO.insert(wkPublish);
            //课时发布作业，根据课程范围生成作业发布范围记录
            if (workPublishDTO.getCourseId() != null) {
                List<CourseRange> cRangeList = courseRangeDAO.selectByCourseId(workPublishDTO.getCourseId());
                WorkPublishRange wkPub;
                Map<String, Object> studentParam = new HashMap<String, Object>();
                StudentWork stuWork;
                for (CourseRange cRange : cRangeList) {
                    //平台范围的课时作业
                    if (cRange.getClassId() == -1 || cRange.getSchoolId() == -1) {

                    } else {
                        studentParam.put("schoolId", cRange.getSchoolId());
                        studentParam.put("classId", cRange.getClassId());
                    }
                    //创建课时作业发布范围
                    wkPub = WorkPublishRange.builder().classId(cRange.getClassId())
                            .schoolId(cRange.getSchoolId())
                            .creator(LoginContextUtil.getAdmin().getId())
                            .createTime(new Date())
                            .workPublishId(wkPublish.getId()).build();
                    workPublishRangeDAO.insert(wkPub);
                    //根据课程范围下的学生,生成作业
                    List<Student> stuList = studentDAO.listQuery(studentParam);
                    for (Student stu : stuList) {
                        stuWork = new StudentWork();
                        stuWork.setClassId(cRange.getClassId());
                        stuWork.setCourseId(wkPublish.getCourseId());
                        stuWork.setFinishState(Byte.parseByte("0"));
                        stuWork.setPublishTime(new Date());
                        stuWork.setLessonPeriodId(wkPublish.getLessonPeriodId());
                        stuWork.setWorkId(wkPublish.getWorkId());
                        stuWork.setWorkPublishId(wkPublish.getId());
                        studentWorkDAO.insert(stuWork);
                    }
                }

            }
            //课时作业发布状态,改成已发布
            if (wkPublish.getLessonPeriodId() != null) {
                LessonPeriod lessonPeriod = lessonPeriodDAO.selectByPrimaryKey(wkPublish.getLessonPeriodId());
                lessonPeriod.setIsWorkPublish(Byte.parseByte("1"));
                lessonPeriodDAO.updateByPrimaryKeySelective(lessonPeriod);
            }
            apiResponse = ApiResponse.success(workPublishDTO);
        } catch (Exception e) {
            apiResponse = ApiResponse.error(ResultCode.PUBLISH_WORK_ERROR, e.getMessage());
            e.printStackTrace();
        }


        return apiResponse;
    }

    public ApiResponse<CourseDetailVO> getCourseDetail(Integer courseId) {
        log.info("获取课程开始执行，课程ID:{}", courseId);
        ApiResponse<CourseDetailVO> apiResponse = null;
        try {
            Course course = courseDAO.selectByPrimaryKey(courseId);
            CourseDetailVO courseVo = new CourseDetailVO.VOBuilder(course).build();
            List<CourseRange> courseRangeList = courseRangeDAO.selectByCourseId(courseId);
            courseVo.setCourseRangeList(courseRangeList);
            List<LessonPeriod> lessonPeriodList = lessonPeriodDAO.selectByCourseId(courseId);
            if (lessonPeriodList != null && lessonPeriodList.size() > 0) {
                for (LessonPeriod lessonPeriod : lessonPeriodList) {
                    Admin admin = adminDAO.selectByPrimaryKey(lessonPeriod.getTeacherId());
                    if (admin != null) {
                        lessonPeriod.setTeacherName(admin.getName());
                    }
                    //计算课时学习进度
                    lessonPeriod.setRate(getLessonPeriodRate(lessonPeriod));
                }
                //计算课程学习进度
                courseVo.setRate(getCourseRate(courseId));
            }
            courseVo.setLessonPeriodList(lessonPeriodList);
            //设置当前课程为正在学习课程 ext3=1
            Student student = LoginContextUtil.getStudent();
            if (student != null) {
                Student newStu = new Student();
                newStu.setId(student.getId());
                newStu.setModified(new Date());
                newStu.setExt3(String.valueOf(courseId));
                studentDAO.updateByPrimaryKeySelective(newStu);
            }
            apiResponse = ApiResponse.success(courseVo);
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        log.info("获取课程执行完成");
        return apiResponse;
    }

    public ApiResponse<List<CourseVO>> findByPageParams(CourseQueryDTO dtoParams) {
        if (LoginContextUtil.getAdmin() != null) {
            //添加数据权限判断
            Admin admin = LoginContextUtil.getAdmin();
            if (admin == null) {
                return ApiResponse.error(ResultCode.INVALID_PARAM);
            }
            List<Integer> ids = new ArrayList<>();
            List<Admin> adminList = new ArrayList<>();
            List<Role> list = roleDAO.selectRoleByAdminId(admin.getId());
            if (list != null && list.size() > 0) {
                if (RoleGroupEnum.SCHOOL_ADMIN.getCode().equals(list.get(0).getRoleGroup().intValue())) {
                    //学校管理员,查看学校创建
                    adminList = adminDAO.selectBySchoolId(admin.getSchoolId());
                } else if (RoleGroupEnum.TEACHER_ADMIN.getCode().equals(list.get(0).getRoleGroup().intValue())) {
                    //教师平台，查看自己创建
                    adminList.add(admin);
                }
                for (Admin ad : adminList) {
                    ids.add(ad.getId());
                }
            }
            dtoParams.setIds(ids);
        }
        log.info("分页获取课程列表开始执行，入参:{}", dtoParams);
        ApiResponse<List<CourseVO>> apiResponse = null;
        Page page = PageHelper.startPage(dtoParams.getPageNo(), dtoParams.getPageSize());
        List<Course> resultList = courseDAO.selectByParam(dtoParams);
        List<CourseVO> voList = new ArrayList<>();
        for (Course q : resultList) {
            CourseVO courseVO = new CourseVO.VOBuilder(q).build();
            voList.add(courseVO);
        }
        PageInfo pageInfo = new PageInfo(page);
        pageInfo.setList(resultList);
        apiResponse = ApiResponse.success(voList, (int) pageInfo.getTotal());
        return apiResponse;
    }

    /**
     * 根据课程计算课程学习进度
     * 课程的完成进度= 课时完成数量/课时总数
     *
     * @param courseId
     * @return
     */
    private String getCourseRate(Integer courseId) {
        int hasFinishCount = 0, total = 0;
        List<LessonPeriod> lessonPeriodList = lessonPeriodDAO.selectByCourseId(courseId);
        if (lessonPeriodList != null && lessonPeriodList.size() > 0) {
            for (LessonPeriod lessonPeriod : lessonPeriodList) {
                total++;
                if ("1".equals(this.getLessonPeriodRate(lessonPeriod))) {
                    hasFinishCount++;
                }
            }
        }
        return getFormatRate(hasFinishCount * 1.0000 / total);
    }

    public ApiResponse<List<MyCourseListVO>> recommendCourseList(PageQueryDTO pageQueryDTO) {
        log.info("分页获取学生端课程列表开始执行");
        ApiResponse<List<MyCourseListVO>> apiResponse = null;
        Page page = PageHelper.startPage(pageQueryDTO.getPageNo(), pageQueryDTO.getPageSize());
        Map<String, Object> queryParam = new HashMap<String, Object>();
        queryParam.put("isOnline", "1");
        if (LoginContextUtil.getStudent() != null) {
            queryParam.put("studentId", LoginContextUtil.getStudent().getId());
        } else {
            return ApiResponse.error(ResultCode.ERROR, "学生未登录");
        }

        List<Course> resultList = courseDAO.recommendCourseList(queryParam);
        List<MyCourseListVO> voList = new ArrayList<>();
        for (Course q : resultList) {
            //下线课程不展示
            if (q.getIsOnline() == 1) {
                //计算课时
                MyCourseListVO coursewareVO = new MyCourseListVO.VOBuilder(q).build();
                voList.add(coursewareVO);
            }
        }

        PageInfo pageInfo = new PageInfo(page);
        pageInfo.setList(resultList);
        apiResponse = ApiResponse.success(voList, (int) pageInfo.getTotal());
        return apiResponse;
    }

    public ApiResponse<List<MyCourseListVO>> myCourseList(MyCourseDTO dtoParams) {
        Map<String, Object> queryParam = new HashMap<String, Object>();
        if (LoginContextUtil.getStudent() != null) {
            queryParam.put("studentId", LoginContextUtil.getStudent().getId());
        } else {
            return ApiResponse.error(ResultCode.ERROR, "学生未登录");
        }
        if (dtoParams.getCompleteState() == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        queryParam.put("isOnline", "1");
        List<MyCourseListVO> finishCourseList = new ArrayList<>();
        List<MyCourseListVO> unFinishCourseList = new ArrayList<>();
        List<Course> resultList = courseDAO.recommendCourseList(queryParam);
        List<MyCourseListVO> voList = new ArrayList<>();
        for (Course q : resultList) {
            MyCourseListVO courseListVO = new MyCourseListVO.VOBuilder(q).build();
            String rate = getCourseRate(courseListVO.getId());
            courseListVO.setRate(rate);
            if (rate.equals("1") || rate.equals("1.0") || rate.equals("1.00") || rate.equals("1.000")) {
                finishCourseList.add(courseListVO);
            } else {
                unFinishCourseList.add(courseListVO);
            }
            voList.add(courseListVO);
        }
        if (dtoParams.getCompleteState() == 1) {
            if (finishCourseList.size() > 0) {
                return ApiResponse.success(finishCourseList.subList(dtoParams.getStartIndex(), Math.min(finishCourseList.size(), dtoParams.getPageSize())));
            }
        } else if (dtoParams.getCompleteState() == 0) {
            if (unFinishCourseList.size() > 0) {
                return ApiResponse.success(unFinishCourseList.subList(dtoParams.getStartIndex(), Math.min(unFinishCourseList.size(), dtoParams.getPageSize())));
            }
        } else {
            if (voList.size() > 0) {
                return ApiResponse.success(voList.subList(dtoParams.getStartIndex(), Math.min(voList.size(), dtoParams.getPageSize())));
            }
        }
        return ApiResponse.success();
    }


    public ApiResponse<Set<Course>> selectCourseByParam(IndexQueryVO indexQueryVO) {
        //业务处理,搜索课程列表,只能搜索自己看到的课程
        List<Course> list = courseDAO.selectCourseByParam(indexQueryVO);
        Student student = LoginContextUtil.getStudent();
        if (student == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        TreeSet<Course> set = new TreeSet<>();
        if (list != null && list.size() > 0) {
            for (Course course : list) {
                if (course.getIsPlatform() != null && course.getIsPlatform() == 1) {
                    set.add(course);
                } else {
                    //查看发布范围
                    List<CourseRange> courseRangeList = courseRangeDAO.selectByCondition(course.getId(), student.getSchoolId(), student.getClassId());
                    if (courseRangeList != null && courseRangeList.size() > 0) {
                        set.add(course);
                    }
                }
            }
        }
        return ApiResponse.success(set);
    }

    public ApiResponse<CourseDetailVO> getStudyCourse() {
        Student student = LoginContextUtil.getStudent();
        if (student == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        if (StringUtil.isEmpty(student.getExt3())) {
            return ApiResponse.success();
        }
        Course course = courseDAO.selectByPrimaryKey(Integer.parseInt(student.getExt3()));
        if (course == null) {
            return ApiResponse.success();
        }
        CourseDetailVO courseVo = new CourseDetailVO.VOBuilder(course).build();
        if (courseVo.getIsOnline() == 0) {
            //课程已下线,则不展示
            return ApiResponse.success();
        }
        return ApiResponse.success(courseVo);
    }

    public ApiResponse<LessonPeriodVO> getLessonPeriodList(CourseDto courseDto) {
        List<LessonPeriod> list = lessonPeriodDAO.selectByCourseId(courseDto.getCourseId());
        List<LessonPeriodVO> resultList = new ArrayList<>();
        for (LessonPeriod lessonPeriod : list) {
            LessonPeriodVO lessonPeriodVO = new LessonPeriodVO.VOBuilder(lessonPeriod).build();
            Admin admin = adminService.get(lessonPeriod.getTeacherId());
            if (admin != null) {
                lessonPeriodVO.setTeacherName(admin.getName());
            }
            resultList.add(lessonPeriodVO);
        }
        return ApiResponse.success(resultList);
    }

    public ApiResponse<LessonPeriodVO> getLessonPeriodAdmin(LessonPeriodDetailDTO lessonPeriodDetailDTO) {
        ApiResponse<LessonPeriodVO> apiResponse = null;
        try {
            Integer lessonPeriodId = lessonPeriodDetailDTO.getLessonPeriodId();
            LessonPeriod lessonPeriod = lessonPeriodDAO.selectByPrimaryKey(lessonPeriodId);
            LessonPeriodVO lessonPeriodVO = new LessonPeriodVO.VOBuilder(lessonPeriod).build();
            if (StringUtil.isNotEmpty(lessonPeriod.getCoursewareIds())) {
                String[] ids = lessonPeriod.getCoursewareIds().split(",");
                List<Courseware> coursewareList = new ArrayList<Courseware>();
                for (String id : ids) {
                    Courseware courseware = coursewareDAO.selectByPrimaryKey(Integer.parseInt(id));
                    coursewareList.add(courseware);
                }
                lessonPeriodVO.setCoursewareList(coursewareList);
            }
            if (lessonPeriod.getTeachingMaterialId() != null) {
                TeachingMaterial tmaterial = materialDAO.selectByPrimaryKey(lessonPeriod.getTeachingMaterialId());
                lessonPeriodVO.setTeachingMaterial(tmaterial);
            }
            if (lessonPeriod.getTeacherId() != null) {
                Admin teacher = adminDAO.selectByPrimaryKey(lessonPeriod.getTeacherId());
                if (teacher != null) lessonPeriodVO.setTeacher(teacher);
            }
            if (lessonPeriod.getWorkId() != null) {
                Work w = workDAO.selectByPrimaryKey(lessonPeriod.getWorkId());
                lessonPeriodVO.setWork(w);
            }
            if (lessonPeriod.getExamId() != null) {
                ExamPaper paper = examkDAO.selectByPrimaryKey(lessonPeriod.getExamId());
                lessonPeriodVO.setExamPaper(paper);
            }
            if (StringUtil.isNotEmpty(lessonPeriod.getTeachingAidIds())) {
                String[] ids = lessonPeriod.getTeachingAidIds().split(",");
                List<TeachingAid> tAidList = new ArrayList<TeachingAid>();
                for (String id : ids) {
                    TeachingAid taid = teachingAidDAO.selectByPrimaryKey(Integer.parseInt(id));
                    tAidList.add(taid);
                }
                lessonPeriodVO.setTeachingAidList(tAidList);
            }
            apiResponse = ApiResponse.success(lessonPeriodVO);
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse unPublishLessonPeriod(UnPublishLessonPeriodDTO unPublishLessonPeriodDTO) {
        if (unPublishLessonPeriodDTO == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        LessonPeriod lessonPeriod = lessonPeriodDAO.selectByPrimaryKey(unPublishLessonPeriodDTO.getLessonPeriodId());
        if (lessonPeriod == null || !lessonPeriod.getCourseId().equals(unPublishLessonPeriodDTO.getCourseId())) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        LessonPeriod newLessionPeriod = new LessonPeriod();
        newLessionPeriod.setId(lessonPeriod.getId());
        newLessionPeriod.setPublishState(unPublishLessonPeriodDTO.getPublishState());
        lessonPeriodDAO.updateByPrimaryKeySelective(newLessionPeriod);
        return ApiResponse.success();
    }

    public ApiResponse<Object> getCourseWareStudyTime(CoursewareStudyDTO coursewareStudyDTO) {
        Student student = LoginContextUtil.getStudent();
        if (student == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        Map<String, Object> param = new HashMap<>(8);
        param.put("courseId", coursewareStudyDTO.getCourseId());
        param.put("lessonPeriodId", coursewareStudyDTO.getLessonPeriodId());
        param.put("coursewareId", coursewareStudyDTO.getCoursewareId());
        param.put("studentId", student.getId());
        List<LearningProgress> list = learningProgressDAO.selectByMapParam(param);
        if (list != null && list.size() > 0) {
            return ApiResponse.success(list.get(0));
        }
        return ApiResponse.error(ResultCode.ERROR, "您还没有学习该课件");
    }

    public ApiResponse<Object> updateCourseWareStudyTime(CoursewareStudyDTO coursewareStudyDTO) {
        Student student = LoginContextUtil.getStudent();
        if (student == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        Map<String, Object> param = new HashMap<>(8);
        param.put("courseId", coursewareStudyDTO.getCourseId());
        param.put("lessonPeriodId", coursewareStudyDTO.getLessonPeriodId());
        param.put("coursewareId", coursewareStudyDTO.getCoursewareId());
        param.put("studentId", student.getId());
        List<LearningProgress> list = learningProgressDAO.selectByMapParam(param);
        if (list == null || list.size() == 0) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        LearningProgress learningProgress = list.get(0);
        learningProgress.setAccumulatedTime(coursewareStudyDTO.getStudyTime() == null ? 0 : coursewareStudyDTO.getStudyTime().intValue());
        //若学习时长>课件推荐时长，完成情况置为已完成
        Courseware courseware = coursewareDAO.selectByPrimaryKey(learningProgress.getCoursewareId());
        if (courseware != null && coursewareStudyDTO.getStudyTime() != null && (coursewareStudyDTO.getStudyTime() * 1.0 / 60 > courseware.getLearningTime())) {
            learningProgress.setCompleteState(((byte) 1));
        }
        learningProgress.setUpdateTime(new Date());
        learningProgress.setVideoWatchTime(coursewareStudyDTO.getVideoWatchTime());
        learningProgressDAO.updateByPrimaryKeySelective(learningProgress);
        return ApiResponse.success();
    }


    public List<AddCourseQuantityVO> getIncrCourse() {
        Date date = new Date();
        List<AddCourseQuantityVO> list = new ArrayList<>();
        for (int i = 6; i >= 0; i--) {
            AddCourseQuantityVO addCourseQuantityVO = new AddCourseQuantityVO();
            DateVO dateVO = DateUtil.getDateRange(date, -i);
            addCourseQuantityVO.setDate(dateVO.getDesc());
            addCourseQuantityVO.setAddQuantity(courseDAO.countByRange(dateVO.getStart(), dateVO.getEnd()));
            list.add(addCourseQuantityVO);
        }
        return list;
    }
}
